package controller

import (
	"equantum/common"
	"equantum/compiler"
	"equantum/dto"
	"equantum/model"
	"equantum/response"
	"errors"
	"log"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
)

type IGateController interface {
	RestController
	ShowBasic(ctx *gin.Context) // 获取基础的gates
	// create: 创建gate
	// update: 更新gate
	// show: 获取用户定义的所有gates
	// delete: 删除gate
}

type GateController struct {
	DB *gorm.DB
}

func NewGateController() IGateController {
	db := common.GetDB()          // 获取数据库连接池
	db.AutoMigrate(&model.Gate{}) // 创建表

	// 向数据库 Gate 插入初始数据
	var gate model.Gate
	err := db.Where("id = ?", 1).First(&gate).Error
	if errors.Is(err, gorm.ErrRecordNotFound) { // 没有初始化数据库
		for _, row := range compiler.InitGates {
			err = db.Create(&row).Error
			if err != nil {
				log.Printf("err init gate table: %v", err)
			}
		}
	}

	return GateController{DB: db} // 创建file controller实例
}

// 创建gate（POST，Name，Type，Param，UserID，Code）
func (c GateController) Create(ctx *gin.Context) {
	// 获取参数
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	// gate
	var newGate model.Gate
	if err := ctx.BindJSON(&newGate); err != nil {
		log.Print(err)
	}
	newGate.UserID = userId

	// 数据验证
	var oldGate model.Gate
	err := c.DB.Where("name = ? AND user_id = ?", newGate.Name, newGate.UserID).First(&oldGate).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) { // 用户userId已经有一个gate叫这名字了
		response.Fail(ctx, nil, "重复的门命名")
		return
	}

	// 插入数据库
	if err := c.DB.Create(&newGate).Error; err != nil {
		response.Fail(ctx, nil, "创建量子门失败")
		return
	}

	// 返回创建结果
	response.Success(ctx, nil, "创建量子门成功")
}

// 更新gate（PUT，用户ID，文件ID，新文件名）
func (c GateController) Update(ctx *gin.Context) {
	// 获取参数
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	// gate
	var updateGate model.Gate
	if err := ctx.BindJSON(&updateGate); err != nil {
		log.Print(err)
	}
	updateGate.UserID = userId

	// 数据验证

	// 检查gate是否存在
	var oldGate model.Gate
	err := c.DB.Where("id = ? AND user_id = ?", updateGate.ID, updateGate.UserID).First(&oldGate).Error
	if errors.Is(err, gorm.ErrRecordNotFound) { // 用户userId没有gate
		response.Fail(ctx, nil, "量子门不存在")
		return
	}

	// 更新gate
	if err = c.DB.Model(&oldGate).Updates(updateGate).Error; err != nil {
		response.Fail(ctx, nil, "更新失败")
		return
	}

	// 返回更新结果
	response.Success(ctx, nil, "更新成功")
}

// 获取用户名下的所有gate（GET，用户ID）
func (c GateController) Show(ctx *gin.Context) {
	// 获取参数
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID

	// 查找用户的所有文件
	var showGates []model.Gate
	if err := c.DB.Where("user_id = ?", userId).Find(&showGates).Error; err != nil {
		response.Fail(ctx, nil, "查询失败")
		return
	}

	// 返回查询结果
	response.Success(ctx, gin.H{"gates": showGates}, "查询成功")
}

// 删除gate（DELETE，用户ID，gateID）
func (c GateController) Delete(ctx *gin.Context) {
	// 获取参数
	user, _ := ctx.Get("user")
	userId := user.(model.User).ID
	gateId := ctx.Params.ByName("id") // 从参数中获取

	// 删除文件
	var deleteGate model.Gate
	if err := c.DB.Where("id = ? AND user_id = ?", gateId, userId).Delete(&deleteGate).Error; err != nil {
		response.Fail(ctx, nil, "删除失败")
		return
	}

	// 返回删除结果
	response.Success(ctx, nil, "删除成功")
}

// 获取基础的gates
func (c GateController) ShowBasic(ctx *gin.Context) {
	// 查找所有基础gates
	var showGates []model.Gate
	if err := c.DB.Where("user_id = 0").Find(&showGates).Error; err != nil {
		response.Fail(ctx, nil, "查询失败")
		return
	}

	// 返回查询结果
	response.Success(ctx, gin.H{"gates": dto.ToGateArrDto(showGates)}, "查询成功")
}
